/*
 * Created on Apr 1, 2004
 *
 * To change the template for this generated file go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
 */
package littlecyberwar.control;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.*;
import javax.swing.*;
import javax.swing.*;
import javax.swing.filechooser.*;
import javax.swing.tree.*;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.event.*;
import java.io.*;
import java.lang.Runnable; 
import java.net.*;

import littlecyberwar.util.*;
import ModuleBuilder.model.*;
import littlecyberwar.control.net.*;
import littlecyberwar.model.*;

/**
 * @author Milton  Soong
 *
 * To change the template for this generated type comment go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
 */
public class GameTypeHandler {
	public static final int _GAME_TYPE_HOTSEAT=0;
	public static final int _GAME_TYPE_PBEM=1;
	public static final int _GAME_TYPE_ONLINE=2;
	public static final String _DEFAULT_SERVER_PORT_STR="7667".intern();
	public static final String _DEFAULT_SERVER_IP_STR="127.0.0.1".intern();
	
	public static void startGame( int gameType, JFrame parent ){
		if ( gameType == _GAME_TYPE_HOTSEAT ){
			handleHotSeatGame(parent);
		} else if (gameType == _GAME_TYPE_PBEM){
			handlePBEMGame(parent );			
		} else if (gameType == _GAME_TYPE_ONLINE){
			handleOnlineGame(parent);
		}
	}
	
	private static void handleHotSeatGame(JFrame parent) {
		getPlayerName(parent);
	}
	
	private static void handlePBEMGame(JFrame parent ) {
		getPlayerName(parent);
	}
	
	/**
	 * Will perform the following:
	 * 1) putup another dialog to ask if the player is a server or a client
	 * 2) if server then spin off a thread to handle connection
	 * 3) if client then spin off another thread to handle client connection 
	 *
	 */
	private static void handleOnlineGame(JFrame parent ) {
		getPlayerName(parent);
		
		// !!! Need to disbale all unit inputs so no units can be moved by mistake
		Object[] options = {"Server",
							"Client"};
		int n = JOptionPane.showOptionDialog(parent,
			"Are you going to host a game as the server?\n"+
			"or connect to someone else's game as the client?",
			"Choose Coonection Type",
			JOptionPane.YES_NO_OPTION,
			JOptionPane.QUESTION_MESSAGE,
			null,     //don't use a custom Icon
			options,  //the titles of buttons
			options[0]); //default button title

		if ( n == 0 ){
			startServer(parent);
		} else {
			startClient(parent);
		}
		return;
	}
	
	private static void getPlayerName(JFrame parent) {
		// first ask for the player name
		Players self=null;
		while ( self == null ){
			String playerName = (String)JOptionPane.showInputDialog(
								parent,
								"Please enter a player name or handle for the game",						
								"Enter Player Name",
								JOptionPane.QUESTION_MESSAGE,
								null,
								null,
								null);
			if (playerName!= null){
				self = new Players(playerName, true);
			} else {
				JOptionPane.showMessageDialog(parent,
					"Please enter a valid user name...",
					"Invalid User Name",
					JOptionPane.ERROR_MESSAGE);											
			}
		}
	}
	/**
	 * 1. Put "Waiting for connection..." message on the menu bar
	 * 2. Put up dialog to ask for user's preferred port (with a default)
	 * 2. Spin off thread to wait for connection
	 *  
	 * @param parent the MainFrame class, which contains the status area where the connection 
	 * Status is to appear
	 */
	private static void startServer(JFrame parent){
		// first get local host address
		InetAddress ip=null;
		try {
			ip = InetAddress.getLocalHost();
		} catch ( UnknownHostException ex ){
			JOptionPane.showMessageDialog(parent,
				"Please use some other utility to figure out\n"+
				"your machine's ip address, and then communicate\n"+
				"that to your opponent.",
				"Can not determine IP address of machine",
				JOptionPane.WARNING_MESSAGE);			
		}
		String ipStr;
		if ( ip != null ){
			ipStr = ip.getHostAddress();
		} else {
			ipStr = "To be Determined...";
		}
				
		int portNum=-1; 
		while ( portNum == -1 ){
			// now put up a dialog to confirm the port 
			String portStr = (String)JOptionPane.showInputDialog(
								parent,
								"Enter a port number where you'll\n"+
								"accept the connection:\n"+
								"(tell your opponent to connect to ip="+ipStr+", port=", 
								"Ready to start an online game",
								JOptionPane.QUESTION_MESSAGE,
								null,
								null,
								_DEFAULT_SERVER_PORT_STR);
			// check if the port string is a valid port
			try {
				portNum = Integer.parseInt(portStr);
			} catch (NumberFormatException ex) {
				JOptionPane.showMessageDialog(parent,
					"Port number entered is not valid.\n"+
					"Please enter a number between 0 and 65535:",
					"Invalid port number",
					JOptionPane.ERROR_MESSAGE);							
			}
		}	// while ( portNum == -1 )
		
		// now we have a valid port number
		ServerThread ss = new ServerThread(parent, ip, portNum);
		ss.start();
	}
	
	/**
	 * 1. ask for a valid inet address
	 * 2. ask for a valid port
	 * 3. spin off a ClientThread
	 * 
	 * @param parent
	 */
	private static void startClient(JFrame parent){
		String ipStr=null; 
		InetAddress ip=null;
		
		while ( ip == null ){
			// now put up a dialog to confirm the im 
			ipStr = (String)JOptionPane.showInputDialog(
								parent,
								"Enter the IP Address of the hosting server\n"+
								"Ask your opponent about his IP address\n"+
								"(it should be of the form: xxx.xxx.xxx.xxx)", 
								"Enter Server IP Address",
								JOptionPane.QUESTION_MESSAGE,
								null,
								null,
								_DEFAULT_SERVER_IP_STR);
			// check if the ip string is a valid ip address
			try {
				 ip = InetAddress.getByName(ipStr);											 
			} catch ( UnknownHostException ex ) {
				JOptionPane.showMessageDialog(parent,
					"server ip number entered is not valid.\n"+
					"Please enter the correct host ip address\n"+
					"(ask your opponent who's hosting the game what the ip address is)",
					"Invalid IP Address",
					JOptionPane.ERROR_MESSAGE);							
					ip = null;
			}
		}	// while ( ip == null )
		// now work on the port number
		int portNum=-1; 
		while ( portNum == -1 ){
			// now put up a dialog to confirm the port 
			String portStr = (String)JOptionPane.showInputDialog(
								parent,
								"Enter a port number where you'll\n"+
								"Connect to the host server:\n"+
								"Ask your opponent about his port number setting\n", 
								"Enter Host Port Number",
								JOptionPane.QUESTION_MESSAGE,
								null,
								null,
								_DEFAULT_SERVER_PORT_STR);
			// check if the port string is a valid port
			try {
				portNum = Integer.parseInt(portStr);
			} catch (NumberFormatException ex) {
				JOptionPane.showMessageDialog(parent,
					"Port number entered is not valid.\n"+
					"Please enter a number between 0 and 65535:",
					"Invalid port number",
					JOptionPane.ERROR_MESSAGE);							
			}
		}	// while ( portNum == -1 )
		
		// now we have a valid ip address and port number
		ClientThread cs = new ClientThread(parent, ip, portNum);
		cs.start();

	}
}
